package org.bingo.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import org.bingo.dto.*;
import org.bingo.entity.Video;
import org.bingo.misc.Result;
import org.bingo.misc.ResultState;
import org.bingo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{userId}/videos")
    public Result getUserVideos(@PathVariable("userId") Long userId) {
        List<Video> videos = userService.getVideosByUserId(userId);
        if (videos == null) {
            return Result.build(ResultState.INVALID_USER_ID, null);
        }

        List<VideoInfoDto> videoInfoDtoList = new ArrayList<>();
        videos.forEach(video -> {
            VideoInfoDto videoInfoDto = new VideoInfoDto();
            videoInfoDto.setUsername(video.getUser().getUsername());
            videoInfoDto.setUserId(video.getUser().getId());
            videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
            videoInfoDto.setDescription(video.getDescription());
            videoInfoDto.setVideoOriginName(video.getVideoOriginName());
            videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
            videoInfoDto.setM3u8Url(video.getM3u8Url());
            videoInfoDto.setId(video.getId());
            videoInfoDto.setLikeCount(video.getLikeCount());
            videoInfoDto.setDuration(video.getVideoIndex().getDuration());
            videoInfoDto.setTitle(video.getTitle());
            videoInfoDto.setType(video.getVideoType().getTypeName());
            videoInfoDtoList.add(videoInfoDto);
        });

        return Result.build(ResultState.OK, videoInfoDtoList);
    }

    @PostMapping("/register")
    public Result register(@RequestBody RegisterDto registerDto) {
        Long userId = userService.register(registerDto.getUsername(),
                registerDto.getPassword(),
                registerDto.getAvatarUrl(),
                registerDto.getDescription());

        if (userId == -1L) {
            return Result.build(ResultState.USERNAME_EXISTS, null);
        }

        return Result.build(ResultState.OK, userId);
    }

    @PostMapping("/login")
    public Result login(@RequestBody LoginDto loginDto) {
        Map<String, Object> loginToken = userService.login(loginDto.getUsername(),
                loginDto.getPassword());

        if (loginToken == null) {
            return Result.build(ResultState.USERNAME_OR_PASSWORD_ERROR, null);
        }

        UserInfoDto selfInfo = userService.getSelfInfo();

        loginToken.put("id", selfInfo.getId());
        loginToken.put("username", selfInfo.getUsername());
        loginToken.put("avatarUrl", selfInfo.getAvatarUrl());
        loginToken.put("description", selfInfo.getDescription());

        return Result.build(ResultState.OK, loginToken);
    }

    @PostMapping("/checklogin")
    public Result checkLogin() {
        return Result.build(ResultState.OK, userService.checkLogin() ? 1 : 0);
    }

    @SaCheckLogin
    @PostMapping("/logout")
    public Result logout() {
        userService.logout();
        return Result.build(ResultState.OK, null);
    }

    @SaCheckLogin
    @PutMapping("/update")
    public Result updateUser(@RequestBody UpdateUserDto updateUserDto) {
        UserInfoDto userInfoDto = null;
        try {
            userInfoDto = userService.updateUser(updateUserDto.getUsername(),
                    updateUserDto.getPassword(),
                    updateUserDto.getAvatarUrl(),
                    updateUserDto.getDescription());
        } catch (Exception e) {
            return Result.build(ResultState.USERNAME_EXISTS, null);
        }

        return Result.build(ResultState.OK, userInfoDto);
    }

    @SaCheckLogin
    @GetMapping("/info")
    public Result selfInfo() {
        UserInfoDto selfInfo = userService.getSelfInfo();
        return Result.build(ResultState.OK, selfInfo);
    }

    @GetMapping("/info/{id}")
    public Result info(@PathVariable("id") Long id) {
        return Result.build(ResultState.OK, userService.info(id));
    }

    @SaCheckLogin
    @PostMapping("/logoff")
    public Result logoff() {
        return Result.build(ResultState.OK, userService.logoff());
    }

    @SaCheckLogin
    @GetMapping("/likedVideos")
    public Result likedVideos() {
        List<Video> videos = userService.getLikedVideo();

        List<VideoInfoDto> videoInfoDtoList = new ArrayList<>();
        videos.forEach(video -> {
            VideoInfoDto videoInfoDto = new VideoInfoDto();
            videoInfoDto.setUsername(video.getUser().getUsername());
            videoInfoDto.setUserId(video.getUser().getId());
            videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
            videoInfoDto.setDescription(video.getDescription());
            videoInfoDto.setVideoOriginName(video.getVideoOriginName());
            videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
            videoInfoDto.setM3u8Url(video.getM3u8Url());
            videoInfoDto.setId(video.getId());
            videoInfoDto.setLikeCount(video.getLikeCount());
            videoInfoDto.setDuration(video.getVideoIndex().getDuration());
            videoInfoDto.setTitle(video.getTitle());
            videoInfoDto.setType(video.getVideoType().getTypeName());
            videoInfoDtoList.add(videoInfoDto);
        });

        return Result.build(ResultState.OK, videoInfoDtoList);
    }

    @SaCheckLogin
    @GetMapping("/collectedVideos")
    public Result collectedVideos() {
        List<Video> videos = userService.getCollectedVideo();

        List<VideoInfoDto> videoInfoDtoList = new ArrayList<>();
        videos.forEach(video -> {
            VideoInfoDto videoInfoDto = new VideoInfoDto();
            videoInfoDto.setUsername(video.getUser().getUsername());
            videoInfoDto.setUserId(video.getUser().getId());
            videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
            videoInfoDto.setDescription(video.getDescription());
            videoInfoDto.setVideoOriginName(video.getVideoOriginName());
            videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
            videoInfoDto.setM3u8Url(video.getM3u8Url());
            videoInfoDto.setId(video.getId());
            videoInfoDto.setLikeCount(video.getLikeCount());
            videoInfoDto.setDuration(video.getVideoIndex().getDuration());
            videoInfoDto.setTitle(video.getTitle());
            videoInfoDto.setType(video.getVideoType().getTypeName());
            videoInfoDtoList.add(videoInfoDto);
        });

        return Result.build(ResultState.OK, videoInfoDtoList);
    }

}
